<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta http-equiv="Content-Style-Type" content="text/css">
  <title></title>
  <meta name="Generator" content="Cocoa HTML Writer">
  <meta name="CocoaVersion" content="824.41">
  <style type="text/css">
    p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #bf0000}
    p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica; min-height: 22.0px}
    p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
    p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
    p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
    p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
    p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
    span.s1 {color: #0000bf}
    span.s2 {color: #007300}
    span.s3 {color: #bf0000}
    span.s4 {color: #000000}
    span.Apple-tab-span {white-space:pre}
  </style>
</head>
<body>
<p class="p1">//SLUGens released under the GNU GPL as extensions for SuperCollider 3, by Nick Collins, http://www.informatics.sussex.ac.uk/users/nc81/</p>
<p class="p2"><b></b><br></p>
<p class="p3"><b>KmeansToBPSet1<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>K-means Oscillator</b></p>
<p class="p2"><b></b><br></p>
<p class="p4"><b>KmeansToBPSet1.ar(freq, numdatapoints, maxnummeans, nummeans, tnewdata, tnewmeans, soft, bufnum, mul, add)</b></p>
<p class="p5"><br></p>
<p class="p4">Uses succesive iterations of a k-means clustering algorithm on random data with random initial means to form break points in a 2-D space. These are then converted to wavetables in output synthesis based on the oscillator frequency.<span class="Apple-converted-space"> </span></p>
<p class="p5"><br></p>
<p class="p4"><b>freq</b>- frequency of oscillator<span class="Apple-converted-space"> </span></p>
<p class="p4"><b>numdatapoints</b>- Initial number of data points</p>
<p class="p4"><b>maxnummeans</b>- Maximum number of means allowed</p>
<p class="p4"><b>nummeans-</b> current num means</p>
<p class="p4"><b>tnewdata</b>- If a trigger is received, reset source data (k-rate)</p>
<p class="p4"><b>tnewmeans</b>- If a trigger is received, reset means (k-rate)</p>
<p class="p4"><b>soft</b>- Proportion to soften means update. If 1.0, immediate update, 0.0 no update, proportion inbetween amount to move from the old mean position to the new mean of the allocated cluster (ie soft k-means).</p>
<p class="p4"><b>bufnum</b>- Number of a Buffer which contains positions for means and data points; see examples below <span class="Apple-converted-space"> </span></p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//defaults</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar,0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(440,20,8,8,<span class="s1">Impulse</span>.kr(5),0),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p1">//softened</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(440,20,4,4,0,<span class="s1">Impulse</span>.kr(5),<span class="s1">MouseX</span>.kr(0.0,1.0)),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(440,20,4,4,0,<span class="s1">Impulse</span>.kr(5)),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(440,20,4,4,<span class="s1">Impulse</span>.kr(5,0.5),<span class="s1">Impulse</span>.kr(5)),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(<span class="s1">MouseX</span>.kr(200,880),20,4,4,<span class="s1">Impulse</span>.kr(<span class="s1">MouseY</span>.kr(1,100,<span class="s2">'exponential'</span>),0.5),<span class="s1">Impulse</span>.kr(<span class="s1">LFNoise1</span>.kr(0.2,5,6))),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(440,30,10,<span class="s1">MouseY</span>.kr(1,10,<span class="s2">'linear'</span>),<span class="s1">Impulse</span>.kr(2,0.5),<span class="s1">Impulse</span>.kr(<span class="s1">LFNoise1</span>.kr(0.2,5,6))),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//pushing up amount of data and num means (also increases CPU cost)</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(440,100,20,<span class="s1">MouseY</span>.kr(1,20,<span class="s2">'linear'</span>),<span class="s1">Impulse</span>.kr(0.2,0.5),<span class="s1">Impulse</span>.kr(<span class="s1">LFNoise1</span>.kr(0.23))),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//pushing up amount of data and num means (also increases CPU cost)</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(<span class="s1">MouseX</span>.kr(20,500,<span class="s2">'exponential'</span>),200,40,<span class="s1">MouseY</span>.kr(1,40,<span class="s2">'linear'</span>),<span class="s1">Impulse</span>.kr(0.57,0.5),<span class="s1">Impulse</span>.kr(<span class="s1">LFNoise1</span>.kr(0.53))),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//softening</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(<span class="s1">MouseX</span>.kr(20,500,<span class="s2">'exponential'</span>),200,20,20,<span class="s1">Impulse</span>.kr(0.57,0.5),<span class="s1">Impulse</span>.kr(<span class="s1">LFNoise1</span>.kr(0.53)),<span class="s1">MouseY</span>.kr(0.0,1.0)),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p1">//softened</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(44+<span class="s1">Dust</span>.kr(10,10),30,10,10,<span class="s1">Impulse</span>.kr(0.1),<span class="s1">Impulse</span>.kr(<span class="s1">LFNoise0</span>.kr(0.4,0.2,0.3)),<span class="s1">MouseX</span>.kr(0.01,1.0,<span class="s2">'exponential'</span>)-0.01),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//modulate</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(<span class="s1">A2K</span>.kr(44+<span class="s1">KmeansToBPSet1</span>.ar(<span class="s1">MouseY</span>.kr(0.1,1000,<span class="s2">'exponential'</span>),soft:0.1,mul:50,add:60)),30,10,10,<span class="s1">Impulse</span>.kr(0.1),<span class="s1">Impulse</span>.kr(<span class="s1">LFNoise0</span>.kr(0.4,0.2,0.3)),<span class="s1">MouseX</span>.kr(0.01,1.0,<span class="s2">'exponential'</span>)-0.01),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//chordal sequence with character</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(<span class="s1">Mix</span>(0.1*<span class="s1">KmeansToBPSet1</span>.ar(220*[1,5/4,3/2,11/7],20,4,4,<span class="s1">Impulse</span>.kr(0.2),<span class="s1">Impulse</span>.kr(10),<span class="s1">MouseX</span>.kr(0.01,0.5,<span class="s2">'exponential'</span>))),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//using a Buffer to select positions for data and reset positions for means</p>
<p class="p6"><br></p>
<p class="p1">//maxmeans will be 5, 20 data points</p>
<p class="p6"><br></p>
<p class="p7">b = <span class="s1">Buffer</span>.alloc(s, (5+20)*2, 1); <span class="s3">//buffer big enough</span></p>
<p class="p6"><br></p>
<p class="p1">//random positions- but they'll be the SAME random positions when resetting</p>
<p class="p1"><span class="s4">b.setn(0,</span><span class="s1">Array</span><span class="s4">.fill(50,{1.0.rand})); </span>//set x,y points (in [0,1] by [0,1] for this UGen)</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(0.1*<span class="s1">KmeansToBPSet1</span>.ar(<span class="s1">MouseX</span>.kr(100,1000,<span class="s2">'exponential'</span>), 20, 5, 5, <span class="s1">Impulse</span>.kr(1), <span class="s1">Impulse</span>.kr(1), <span class="s1">MouseY</span>.kr(0.01,1.0),b.bufnum),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p1">//change buffer when you like:</p>
<p class="p6"><br></p>
<p class="p1">//change data</p>
<p class="p1"><span class="s4">b.setn(0,</span><span class="s1">Array</span><span class="s4">.fill(40,{1.0.rand})); </span>//set x,y points (in [0,1] by [0,1] for this UGen)</p>
<p class="p6"><br></p>
<p class="p1">//change means</p>
<p class="p1"><span class="s4">b.setn(40,</span><span class="s1">Array</span><span class="s4">.fill(10,{1.0.rand})); </span>//set x,y points (in [0,1] by [0,1] for this UGen)</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//buffer version</p>
<p class="p7">{<span class="s1">Out</span>.ar(0,<span class="s1">Pan2</span>.ar(<span class="s1">Mix</span>(0.1*<span class="s1">KmeansToBPSet1</span>.ar(220*[1,5/4,3/2,11/7],20,5,5,<span class="s1">Impulse</span>.kr(10),<span class="s1">Impulse</span>.kr(10),<span class="s1">MouseX</span>.kr(0.01,0.5,<span class="s2">'exponential'</span>), b.bufnum)),0.0))}.play</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//routine playing with mean initial positions</p>
<p class="p7">(</p>
<p class="p7">c= {<span class="s1">inf</span>.do{</p>
<p class="p6"><br></p>
<p class="p7">b.setn(40,<span class="s1">Array</span>.fill(10,{1.0.rand}));<span class="Apple-converted-space"> </span></p>
<p class="p6"><br></p>
<p class="p7"><span class="Apple-converted-space"> </span>rrand(0.1,0.2).wait;}}.fork</p>
<p class="p6"><br></p>
<p class="p7">)</p>
<p class="p7">c.stop;</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p1">//routine playing with data positions</p>
<p class="p6"><br></p>
<p class="p7">(</p>
<p class="p7">d= {<span class="s1">inf</span>.do{</p>
<p class="p6"><br></p>
<p class="p7">b.setn(0,<span class="s1">Array</span>.fill(40,{1.0.rand}));<span class="Apple-converted-space"> </span></p>
<p class="p6"><br></p>
<p class="p7"><span class="Apple-converted-space"> </span>rrand(0.1,0.2).wait;}}.fork</p>
<p class="p6"><br></p>
<p class="p7">)</p>
<p class="p6"><br></p>
<p class="p7">c.stop;</p>
<p class="p7">d.stop;</p>
</body>
</html>
